import React, {useState} from 'react';
import {App, Button, Drawer, Form, Space, Table, Typography} from 'antd';
import {useReimburseAndState} from "./DetailsComponent";
import LogFactory from "log/LogFactory";
import {requestDelete, requestGet} from "util/request";
import {getTag} from "util/ColumnsUtil";
import {uuid32} from "util/uuid";
import {DetailsOptionProps} from "../../../../redux/reducer/reimburseDetailReducer";
import {fetchAddItemOptions, fetchUpdateItemOptions} from "../../../../redux/reducer/async/detailsAsyncAction";
import {PlusOutlined} from "@ant-design/icons";
import {inputMap} from "maps/init";

const log = LogFactory.getLog("Reimburse.Details.Option");

interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
    editing: boolean;
    dataIndex: string;
    title: any;
    inputType: 'number' | 'text' | 'boolean';
    record: DetailsOptionProps;
    index: number;
    children: React.ReactNode;
    align: "left" | "right" | "center" ;
}
const inputTypeMap = new Map<string, string>();
inputTypeMap.set("label","text");
inputTypeMap.set("value","text");
inputTypeMap.set("order","number");
inputTypeMap.set("hide","boolean");
inputTypeMap.set("defaultChecked","boolean");
/**
 * 编辑表的表单生成
 * @param editing
 * @param dataIndex
 * @param title
 * @param inputType
 * @param record
 * @param index
 * @param children
 * @param restProps
 * @constructor
 */
const EditableCell: React.FC<EditableCellProps> = ({editing, dataIndex, title, inputType, record, index, children, ...restProps}) => {
    const inputNode = inputMap.get(inputType);
    return (
        <td {...restProps}>
            {editing ? (
                <Form.Item
                    name={dataIndex}
                    style={{ margin: 0 }}
                    rules={[
                        {
                            required: true,
                            message: `请输入选项值 ${title}!`,
                        },
                    ]}
                >
                    {inputNode}
                </Form.Item>
            ) : (
                children
            )}
        </td>
    );
};

const DetailsOptionComponent: React.FC = () => {

    const {message} = App.useApp() ;
    const {reimburseId, state, navigate,dispatch} = useReimburseAndState();
    const [form] = Form.useForm<DetailsOptionProps>();
    const [data, setData] = useState<DetailsOptionProps[]>([]);
    const [editingKey, setEditingKey] = useState('');
    const [addKey, setAddKey] = useState<string>();

    /**
     * 页面关闭的回调
     */
    const onClose = () => navigate(".", {replace: true, state: {reimburseId, totalAmount: state.totalMoney}});
    const afterOpenChange = async () => {
            requestGet<DetailsOptionProps[]>("/record/reimburse-details/item-options")
                .then(res => {
                    res.success && setData(res.data) ;
                }) ;
    } ;

    /**
     * 判断当前行是否处于编辑状态
     */
    const isEditing = (record: DetailsOptionProps): boolean => record.key === editingKey;
    /**
     * 当点击表个的编辑 触发此方法
     */
    const edit = (record: Partial<DetailsOptionProps> & { key: React.Key }) => {
        // 当点击编辑时,将当前行的数据设置到表单中___ 设置空数据到表单中
        form.setFieldsValue({ label: '', value: '', order: 0, hide: false, defaultChecked: false,...record });
        // 设置编辑行的key
        setEditingKey(record.key);
    };
    /**
     * 取消编辑时调用
     */
    const cancel = () => {
        if (addKey === editingKey){
        // 如果当前行是新增行,则删除此行
            setData(data.filter(item => item.key !== editingKey));
        }
        setEditingKey('');
        setAddKey(undefined) ;
    };
    const saveHandler = async (data: DetailsOptionProps) => {
        let res = await dispatch(fetchAddItemOptions(data)).unwrap() ;
        if (res.data > 0) {
            log.debug("添加选项成功!");
            message.success("添加选项成功") ;
        }else {
            log.debug("添加选项失败!") ;
        }
    } ;
    const updateHandler = async (data: DetailsOptionProps) => {
            // let res = await requestPost<number>("/record/reimburse-details/item-options",data).then(res => res) ;
        let res = await dispatch(fetchUpdateItemOptions(data)).unwrap() ;
            if (res.data > 0) {
                log.debug("修改选项成功!") ;
                message.success("修改选项成功") ;
            }else {
                log.debug("修改选项失败!") ;
            }
    } ;
    const onDelete = async (rec: DetailsOptionProps) => {
        let res = await requestDelete<number>("/record/reimburse-details/item-options",rec).then(res => res) ;
        if (res.data > 0){
            message.success("删除成功") ;
            setData(data.filter(i => i.key !== rec.key)) ;
        }else {
            message.warning("删除失败") ;
        }
    } ;
    const save = async (key: React.Key) => {
        log.debug("save",key) ;
        try {
            // row = 编辑行的(修改)数据  验证当前行的数据
            const row = (await form.validateFields()) as DetailsOptionProps;
            log.debug("save-row",row) ;
            const newData = [...data];
            // 使用key查找编辑的值(原始值)
            const index = newData.findIndex((item) => key === item.key);
            row.value = row.label ;
            row.key = key as string ;
            log.debug("save-newData",addKey,editingKey) ;
            if (addKey){
                await saveHandler(row) ;
                setAddKey(undefined) ;
                setEditingKey('') ;
            }
            if (editingKey && !addKey){
                await updateHandler(row) ;
                setEditingKey('') ;
            }
            if (index > -1) {
                const item = newData[index];
                // 修改数据集合
                newData.splice(index, 1, {
                    ...item,
                    ...row,
                });
            } else {
                // 如果没有找到key,则新增一条数据
                newData.push(row);
            }
            setData(newData);
        } catch (errInfo) {
            log.info('Validate Failed:', errInfo);
        }
    };
    /**
     * 添加数据
     */
    const add = async () => {
        let a: any = {key: uuid32()} ;
        setData([...data,a]) ;
        setEditingKey(a.key) ;
        setAddKey(a.key) ;
        form.setFieldsValue({ label: '', value: '', order: 1, hide: false, defaultChecked: false, key: a.key });
    } ;

    const optionColumns = [
        {
            title: '选项',
            dataIndex: 'label',
            align: "center",
            editable: true,
        },
        {
            title: '排序',
            dataIndex: 'order',
            align: "center",
            editable: true,
        },
        {
            title: '隐藏',
            dataIndex: 'hide',
            align: "center",
            editable: true,
            render: (value: boolean) => getTag(value,"是","否")
        },
        {
            title: '默认选中',
            dataIndex: 'defaultChecked',
            align: "center",
            editable: true,
            render: (value: boolean) => getTag(value,"是","否")
        },
        {
            title: '操作',
            key: 'operation' ,
            align: "center",
            width: 100,
            dataIndex: 'operation',
            render: (_: any, record: DetailsOptionProps) => {
                if (isEditing(record)){
                    // 如果当前行处于编辑状态,则显示保存和取消按钮
                    return (
                        <span>
                                    <Typography.Link onClick={() => save(record.key)} style={{ marginRight: 8 }}>
                                    保存
                                </Typography.Link>
                                <Button style={{padding: 0}} type={"link"} onClick={cancel}>取消</Button>
                              </span>
                    );
                }else {
                    // 如果当前行不处于编辑状态,则显示编辑按钮
                    return (
                        <Space>
                            <Typography.Link disabled={editingKey !== ''} onClick={() => edit(record)}>
                                编辑
                            </Typography.Link>
                            <Button style={{padding: 0}} type={"link"} danger={true} disabled={ editingKey !== "" } onClick={() => onDelete(record)}>删除</Button>
                        </Space>
                    );
                }
            },
        },
    ];
    const mergedOptionColumns = optionColumns.map((col) => {
        if (!col.editable) {
            return col;
        }
        return {
            ...col,
            onCell: (record: DetailsOptionProps) => ({
                record,
                inputType: inputTypeMap.get(col.dataIndex),
                dataIndex: col.dataIndex,
                title: col.title,
                editing: isEditing(record),
                align: col.align
            }),
        };
    });

    return (
        <Drawer
            title={"编辑报销选项"}
            size={"large"}
            afterOpenChange={afterOpenChange}
            destroyOnClose={true}
            open={true}
            onClose={onClose}
            maskClosable={false}
            extra={ <Button type={"primary"} onClick={add} icon={<PlusOutlined/>}>添加</Button> }
        >
        <Form form={form} component={false}>
            <Table
                loading={false}
                components={{
                    body: {
                        cell: EditableCell,
                    },
                }}
                bordered
                size={"small"}
                dataSource={data}
                // columns={mergedColumns as any}
                columns={mergedOptionColumns as any}
                rowClassName="editable-row"
                pagination={{
                    onChange: cancel,
                }}
            />
        </Form>
            </Drawer>
    );
};
export default DetailsOptionComponent;